package com.moyuaninfo.myyserver.queue;

import cn.hutool.core.thread.ThreadUtil;
import com.moyuaninfo.myyhikwork.hik.HikSdk;
import com.moyuaninfo.myyserver.enums.GetLastErrorEnum;
import com.moyuaninfo.myyserver.vo.HikPtzControlOtherVo;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @author 邱祥霸
 * @date 2020/4/29
 */
public class OperateQueue implements Runnable{

    public static DelayQueue<OperateMessage> deque = new DelayQueue<>();

    @Slf4j
    public static class OperateMessage implements Delayed, Runnable {
        private long fireTime;

        private HikPtzControlOtherVo hikPtzControlOtherVo;

        public OperateMessage(long fireTime, HikPtzControlOtherVo hikPtzControlOtherVo) {
            this.fireTime = fireTime;
            this.hikPtzControlOtherVo = hikPtzControlOtherVo;
        }

        @Override
        public void run() {
            HikSdk hik = new HikSdk(hikPtzControlOtherVo.getDvr().getDvrIp(), (short) hikPtzControlOtherVo.getDvr().getDvrPort(), hikPtzControlOtherVo.getDvr().getDvrUsername(), hikPtzControlOtherVo.getDvr().getDvrPassword());

            try {
                // 初始化SDK
                hik.initSdk();

                // 注册设备
                if (hik.loginSdk() != GetLastErrorEnum.NET_DVR_NOERROR.getValue()) {
                    log.error("注册设备失败");
                    return;
                }
                hik.hikPtzControlWithSpeed(hikPtzControlOtherVo.getDvr().getDvrChannel(), hikPtzControlOtherVo.getDwPtzCommand().getValue(), hikPtzControlOtherVo.getDwStop(), hikPtzControlOtherVo.getDwSpeed());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 注销设备
                hik.logoutSdk();
                // 释放SDK资源
                hik.cleanUp();
            }
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(this.fireTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(Delayed o) {
            return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
        }
    }


    @Override
    public void run() {
        while (true) {
            if (deque.size() <= 0){continue;}
            try {
                OperateMessage operateMessage = deque.take();
                ThreadUtil.execute(operateMessage);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
